ํจ๊ณผ์ ์ธ ์์ฒญ ์ปจํ ์คํธ ๊ด๋ฆฌ๋ฅผ ์ํ JavaScript Async Local Storage(ALS)๋ฅผ ํ์ํ์ธ์. ๋น๋๊ธฐ ์์ ์ ๋ฐ์ ๊ฑธ์ณ ๋ฐ์ดํฐ๋ฅผ ์ถ์ ํ๊ณ ๊ณต์ ํ์ฌ ๋ฐ์ดํฐ ์ผ๊ด์ฑ์ ๋ณด์ฅํ๊ณ ๋๋ฒ๊น ์ ๋จ์ํํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์๋ณด์ธ์.
JavaScript Async Local Storage: ์์ฒญ ์ปจํ ์คํธ ๊ด๋ฆฌ ๋ง์คํฐํ๊ธฐ
ํ๋ JavaScript ๊ฐ๋ฐ, ํนํ ์๋ง์ ๋์ ์์ฒญ์ ์ฒ๋ฆฌํ๋ Node.js ํ๊ฒฝ์์๋ ๋น๋๊ธฐ ์์ ์ ๋ฐ์ ๊ฑธ์ณ ์ปจํ ์คํธ๋ฅผ ํจ๊ณผ์ ์ผ๋ก ๊ด๋ฆฌํ๋ ๊ฒ์ด ๋ฌด์๋ณด๋ค ์ค์ํฉ๋๋ค. ๊ธฐ์กด์ ์ ๊ทผ ๋ฐฉ์์ ์ข ์ข ๋ถ์กฑํ์ฌ ๋ณต์กํ ์ฝ๋์ ์ ์ฌ์ ์ธ ๋ฐ์ดํฐ ๋ถ์ผ์น๋ฅผ ์ด๋ํฉ๋๋ค. ๋ฐ๋ก ์ด ์ง์ ์์ JavaScript Async Local Storage(ALS)๊ฐ ๋น์ ๋ฐํ๋ฉฐ, ํน์ ๋น๋๊ธฐ ์คํ ์ปจํ ์คํธ์ ๋ก์ปฌ์ธ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ ๊ฒ์ํ๋ ๊ฐ๋ ฅํ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค. ์ด ๊ธ์ JavaScript ์ ํ๋ฆฌ์ผ์ด์ ์์ ๊ฒฌ๊ณ ํ ์์ฒญ ์ปจํ ์คํธ ๊ด๋ฆฌ๋ฅผ ์ํด ALS๋ฅผ ์ดํดํ๊ณ ํ์ฉํ๋ ํฌ๊ด์ ์ธ ๊ฐ์ด๋๋ฅผ ์ ๊ณตํฉ๋๋ค.
Async Local Storage(ALS)๋ ๋ฌด์์ธ๊ฐ?
Node.js์ ํต์ฌ ๋ชจ๋(v13.10.0์์ ๋์ ๋์ด ์ดํ ์์ ํ๋จ)๋ก ์ฌ์ฉ ๊ฐ๋ฅํ Async Local Storage๋ ์น ์์ฒญ ์ฒ๋ฆฌ์ ๊ฐ์ ๋น๋๊ธฐ ์์ ์ ์๋ช ์ฃผ๊ธฐ ๋์ ์ ๊ทผํ ์ ์๋ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ์ ์๊ฒ ํด์ค๋๋ค. ์ด๊ฒ์ ์ค๋ ๋-๋ก์ปฌ ์คํ ๋ฆฌ์ง ๋ฉ์ปค๋์ฆ๊ณผ ์ ์ฌํ์ง๋ง JavaScript์ ๋น๋๊ธฐ์ ํน์ฑ์ ๋ง์ถฐ์ง ๊ฒ์ผ๋ก ์๊ฐํ ์ ์์ต๋๋ค. ์ด๋ ๋ชจ๋ ํจ์์ ๋ช ์์ ์ผ๋ก ์ปจํ ์คํธ๋ฅผ ์ธ์๋ก ์ ๋ฌํ์ง ์๊ณ ๋ ์ฌ๋ฌ ๋น๋๊ธฐ ํธ์ถ์ ๊ฑธ์ณ ์ปจํ ์คํธ๋ฅผ ์ ์งํ๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค.
ํต์ฌ ์์ด๋์ด๋ ๋น๋๊ธฐ ์์ (์: HTTP ์์ฒญ ์์ )์ด ์์๋ ๋ ํด๋น ์์ ์ ์ฐ๊ฒฐ๋ ์ ์ฅ ๊ณต๊ฐ์ ์ด๊ธฐํํ ์ ์๋ค๋ ๊ฒ์ ๋๋ค. ํด๋น ์์ ์ ์ํด ์ง๊ฐ์ ์ ์ผ๋ก ํธ๋ฆฌ๊ฑฐ๋ ๋ชจ๋ ํ์ ๋น๋๊ธฐ ํธ์ถ์ ๋์ผํ ์ ์ฅ ๊ณต๊ฐ์ ์ ๊ทผํ ์ ์์ต๋๋ค. ์ด๋ ํน์ ์์ฒญ์ด๋ ํธ๋์ญ์ ๊ณผ ๊ด๋ จ๋ ์ํ๋ฅผ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ๋ฌ ๋ถ๋ถ์ ํต๊ณผํ๋ฉด์ ์ ์งํ๋ ๋ฐ ๋งค์ฐ ์ค์ํฉ๋๋ค.
Async Local Storage๋ฅผ ์ฌ์ฉํ๋ ์ด์
ALS๊ฐ ์์ฒญ ์ปจํ ์คํธ ๊ด๋ฆฌ๋ฅผ ์ํ ๋งค๋ ฅ์ ์ธ ์๋ฃจ์ ์ด ๋๋ ๋ช ๊ฐ์ง ์ฃผ์ ์ด์ ์ด ์์ต๋๋ค:
- ์ฝ๋ ๋จ์ํ: ๋ชจ๋ ํจ์์ ์ปจํ ์คํธ ๊ฐ์ฒด๋ฅผ ์ธ์๋ก ์ ๋ฌํ๋ ๊ฒ์ ํผํ์ฌ ๋ ๊นจ๋ํ๊ณ ๊ฐ๋ ์ฑ ๋์ ์ฝ๋๋ฅผ ๋ง๋ญ๋๋ค. ์ด๋ ์ผ๊ด๋ ์ปจํ ์คํธ ์ ํ๋ฅผ ์ ์งํ๋ ๊ฒ์ด ์๋นํ ๋ถ๋ด์ด ๋ ์ ์๋ ๋๊ท๋ชจ ์ฝ๋๋ฒ ์ด์ค์์ ํนํ ์ ์ฉํฉ๋๋ค.
- ์ ์ง๋ณด์์ฑ ํฅ์: ์ปจํ ์คํธ๋ฅผ ์ค์๋ก ๋๋ฝํ๊ฑฐ๋ ์๋ชป ์ ๋ฌํ ์ํ์ ์ค์ฌ ๋ ์ ์ง๋ณด์ํ๊ธฐ ์ฝ๊ณ ์ ๋ขฐํ ์ ์๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ง๋ญ๋๋ค. ALS ๋ด์์ ์ปจํ ์คํธ ๊ด๋ฆฌ๋ฅผ ์ค์ ์ง์คํํจ์ผ๋ก์จ ์ปจํ ์คํธ ๋ณ๊ฒฝ ๊ด๋ฆฌ๊ฐ ๋ ์ฌ์์ง๊ณ ์ค๋ฅ ๋ฐ์ ๊ฐ๋ฅ์ฑ์ด ์ค์ด๋ญ๋๋ค.
- ํฅ์๋ ๋๋ฒ๊น : ํน์ ์์ฒญ๊ณผ ๊ด๋ จ๋ ์ปจํ ์คํธ๋ฅผ ๊ฒ์ฌํ ์ ์๋ ์ค์ ์์น๋ฅผ ์ ๊ณตํ์ฌ ๋๋ฒ๊น ์ ๋จ์ํํฉ๋๋ค. ๋ฐ์ดํฐ์ ํ๋ฆ์ ์ฝ๊ฒ ์ถ์ ํ๊ณ ์ปจํ ์คํธ ๋ถ์ผ์น์ ๊ด๋ จ๋ ๋ฌธ์ ๋ฅผ ์๋ณํ ์ ์์ต๋๋ค.
- ๋ฐ์ดํฐ ์ผ๊ด์ฑ: ๋น๋๊ธฐ ์์ ๋ด๋ด ๋ฐ์ดํฐ๊ฐ ์ผ๊ด๋๊ฒ ์ฌ์ฉ ๊ฐ๋ฅํ๋๋ก ๋ณด์ฅํ์ฌ ๊ฒฝ์ ์กฐ๊ฑด ๋ฐ ๊ธฐํ ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํฉ๋๋ค. ์ด๋ ๋ณต์กํ ํธ๋์ญ์ ์ด๋ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ํ์ดํ๋ผ์ธ์ ์ํํ๋ ์ ํ๋ฆฌ์ผ์ด์ ์์ ํนํ ์ค์ํฉ๋๋ค.
- ์ถ์ ๋ฐ ๋ชจ๋ํฐ๋ง: ์์ฒญ ๊ด๋ จ ์ ๋ณด(์: ์์ฒญ ID, ์ฌ์ฉ์ ID)๋ฅผ ALS ๋ด์ ์ ์ฅํ์ฌ ์์ฒญ ์ถ์ ๋ฐ ๋ชจ๋ํฐ๋ง์ ์ฉ์ดํ๊ฒ ํฉ๋๋ค. ์ด ์ ๋ณด๋ ์์คํ ์ ์ฌ๋ฌ ๋ถ๋ถ์ ํต๊ณผํ๋ ์์ฒญ์ ์ถ์ ํ๋ ๋ฐ ์ฌ์ฉ๋ ์ ์์ผ๋ฉฐ ์ฑ๋ฅ ๋ฐ ์ค๋ฅ์จ์ ๋ํ ๊ท์คํ ํต์ฐฐ๋ ฅ์ ์ ๊ณตํฉ๋๋ค.
Async Local Storage์ ํต์ฌ ๊ฐ๋
ALS๋ฅผ ํจ๊ณผ์ ์ผ๋ก ์ฌ์ฉํ๋ ค๋ฉด ๋ค์ ํต์ฌ ๊ฐ๋ ์ ์ดํดํ๋ ๊ฒ์ด ํ์์ ์ ๋๋ค:
- AsyncLocalStorage: ALS ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ณ ๊ด๋ฆฌํ๊ธฐ ์ํ ์ฃผ์ ํด๋์ค์
๋๋ค.
AsyncLocalStorage์ ์ธ์คํด์ค๋ฅผ ์์ฑํ์ฌ ๋น๋๊ธฐ ์์ ์ ํนํ๋ ์ ์ฅ ๊ณต๊ฐ์ ์ ๊ณตํฉ๋๋ค. - run(store, fn, ...args): ์ ๊ณต๋ ํจ์
fn์ ์ฃผ์ด์งstore์ ์ปจํ ์คํธ ๋ด์์ ์คํํฉ๋๋ค.store๋fn๋ด์์ ์์๋ ๋ชจ๋ ๋น๋๊ธฐ ์์ ์์ ์ฌ์ฉํ ์ ์๋ ์์์ ๊ฐ์ ๋๋ค.fn๋ฐ ๊ทธ ๋น๋๊ธฐ ์์๋ค์ ์คํ ์ค์ ํ์์ ์ผ๋กgetStore()๋ฅผ ํธ์ถํ๋ฉด ์ดstore๊ฐ์ด ๋ฐํ๋ฉ๋๋ค. - enterWith(store): ํน์
store๋ก ์ปจํ ์คํธ์ ๋ช ์์ ์ผ๋ก ๋ค์ด๊ฐ๋๋ค. ์ด๋ `run`๋ณด๋ค ๋ ์ผ๋ฐ์ ์ด์ง๋ง, ํนํ ์ด๊ธฐ ์์ ์ ์ํด ์ง์ ํธ๋ฆฌ๊ฑฐ๋์ง ์์ ๋น๋๊ธฐ ์ฝ๋ฐฑ์ ์ฒ๋ฆฌํ ๋ ํน์ ์๋๋ฆฌ์ค์์ ์ ์ฉํ ์ ์์ต๋๋ค. ์๋ชป ์ฌ์ฉํ๋ฉด ์ปจํ ์คํธ ์ ์ถ๋ก ์ด์ด์ง ์ ์์ผ๋ฏ๋ก ์ฌ์ฉ ์ ์ฃผ์ํด์ผ ํฉ๋๋ค. - exit(fn): ํ์ฌ ์ปจํ ์คํธ๋ฅผ ๋๊ฐ๋๋ค. `enterWith`์ ํจ๊ป ์ฌ์ฉ๋ฉ๋๋ค.
- getStore(): ํ์ฑ ๋น๋๊ธฐ ์ปจํ
์คํธ์ ์ฐ๊ด๋ ํ์ฌ store ๊ฐ์ ๊ฒ์ํฉ๋๋ค. ํ์ฑ store๊ฐ ์์ผ๋ฉด
undefined๋ฅผ ๋ฐํํฉ๋๋ค. - disable(): AsyncLocalStorage ์ธ์คํด์ค๋ฅผ ๋นํ์ฑํํฉ๋๋ค. ๋นํ์ฑํ๋๋ฉด ์ดํ์ `run` ๋๋ `enterWith` ํธ์ถ์ ์ค๋ฅ๋ฅผ ๋ฐ์์ํต๋๋ค. ์ด๋ ์ข ์ข ํ ์คํธ๋ ์ ๋ฆฌ ์ค์ ์ฌ์ฉ๋ฉ๋๋ค.
Async Local Storage์ ์ค์ ์ฌ์ฉ ์์
๋ค์ํ ์๋๋ฆฌ์ค์์ ALS๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ฃผ๋ ๋ช ๊ฐ์ง ์ค์ ์์ ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์์ 1: ์น ์๋ฒ์์ ์์ฒญ ID ์ถ์ ํ๊ธฐ
์ด ์์ ๋ ์น ์์ฒญ ๋ด์ ๋ชจ๋ ๋น๋๊ธฐ ์์ ์์ ๊ณ ์ ํ ์์ฒญ ID๋ฅผ ์ถ์ ํ๊ธฐ ์ํด ALS๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค.
const { AsyncLocalStorage } = require('async_hooks');
const express = require('express');
const uuid = require('uuid');
const asyncLocalStorage = new AsyncLocalStorage();
const app = express();
app.use((req, res, next) => {
const requestId = uuid.v4();
asyncLocalStorage.run(new Map(), () => {
asyncLocalStorage.getStore().set('requestId', requestId);
next();
});
});
app.get('/', (req, res) => {
const requestId = asyncLocalStorage.getStore().get('requestId');
console.log(`Handling request with ID: ${requestId}`);
res.send(`Request ID: ${requestId}`);
});
app.get('/another-route', async (req, res) => {
const requestId = asyncLocalStorage.getStore().get('requestId');
console.log(`Handling another route with ID: ${requestId}`);
// Simulate an asynchronous operation
await new Promise(resolve => setTimeout(resolve, 100));
const requestIdAfterAsync = asyncLocalStorage.getStore().get('requestId');
console.log(`Request ID after async operation: ${requestIdAfterAsync}`);
res.send(`Another route - Request ID: ${requestId}`);
});
app.listen(3000, () => {
console.log('Server listening on port 3000');
});
์ด ์์ ์์๋:
AsyncLocalStorage์ธ์คํด์ค๊ฐ ์์ฑ๋ฉ๋๋ค.- ๋ฏธ๋ค์จ์ด ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ ๋ค์ด์ค๋ ์์ฒญ์ ๋ํด ๊ณ ์ ํ ์์ฒญ ID๋ฅผ ์์ฑํฉ๋๋ค.
asyncLocalStorage.run()๋ฉ์๋๋ ์์ฒญ ID๋ฅผ ์ ์ฅํ๋ ์๋ก์ดMap์ ์ปจํ ์คํธ ๋ด์์ ์์ฒญ ํธ๋ค๋ฌ๋ฅผ ์คํํฉ๋๋ค.- ์์ฒญ ID๋ ๋น๋๊ธฐ ์์
ํ์๋
asyncLocalStorage.getStore().get('requestId')๋ฅผ ํตํด ๋ผ์ฐํธ ํธ๋ค๋ฌ ๋ด์์ ์ ๊ทผํ ์ ์์ต๋๋ค.
์์ 2: ์ฌ์ฉ์ ์ธ์ฆ ๋ฐ ๊ถํ ๋ถ์ฌ
ALS๋ ์ธ์ฆ ํ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ์ ์ฅํ๋ ๋ฐ ์ฌ์ฉ๋ ์ ์์ผ๋ฉฐ, ์ด๋ฅผ ์์ฒญ ์๋ช ์ฃผ๊ธฐ ์ ๋ฐ์ ๊ฑธ์ณ ๊ถํ ๋ถ์ฌ ํ์ธ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
const { AsyncLocalStorage } = require('async_hooks');
const express = require('express');
const asyncLocalStorage = new AsyncLocalStorage();
const app = express();
// Mock authentication middleware
const authenticateUser = (req, res, next) => {
// Simulate user authentication
const userId = 123; // Example user ID
const userRoles = ['admin', 'editor']; // Example user roles
asyncLocalStorage.run(new Map(), () => {
asyncLocalStorage.getStore().set('userId', userId);
asyncLocalStorage.getStore().set('userRoles', userRoles);
next();
});
};
// Mock authorization middleware
const authorizeUser = (requiredRole) => {
return (req, res, next) => {
const userRoles = asyncLocalStorage.getStore().get('userRoles') || [];
if (userRoles.includes(requiredRole)) {
next();
} else {
res.status(403).send('Unauthorized');
}
};
};
app.use(authenticateUser);
app.get('/admin', authorizeUser('admin'), (req, res) => {
const userId = asyncLocalStorage.getStore().get('userId');
res.send(`Admin page - User ID: ${userId}`);
});
app.get('/editor', authorizeUser('editor'), (req, res) => {
const userId = asyncLocalStorage.getStore().get('userId');
res.send(`Editor page - User ID: ${userId}`);
});
app.get('/public', (req, res) => {
const userId = asyncLocalStorage.getStore().get('userId');
res.send(`Public page - User ID: ${userId}`); // Still accessible
});
app.listen(3000, () => {
console.log('Server listening on port 3000');
});
์ด ์์ ์์๋:
authenticateUser๋ฏธ๋ค์จ์ด๋ ์ฌ์ฉ์ ์ธ์ฆ์ ์๋ฎฌ๋ ์ด์ ํ๊ณ ์ฌ์ฉ์ ID์ ์ญํ ์ ALS์ ์ ์ฅํฉ๋๋ค.authorizeUser๋ฏธ๋ค์จ์ด๋ ALS์์ ์ฌ์ฉ์ ์ญํ ์ ๊ฒ์ํ์ฌ ์ฌ์ฉ์์๊ฒ ํ์ํ ์ญํ ์ด ์๋์ง ํ์ธํฉ๋๋ค.- ์ฌ์ฉ์ ID๋ ์ธ์ฆ ํ ๋ชจ๋ ๋ผ์ฐํธ์์ ์ ๊ทผํ ์ ์์ต๋๋ค.
์์ 3: ๋ฐ์ดํฐ๋ฒ ์ด์ค ํธ๋์ญ์ ๊ด๋ฆฌ
ALS๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํธ๋์ญ์ ์ ๊ด๋ฆฌํ๋ ๋ฐ ์ฌ์ฉ๋ ์ ์์ผ๋ฉฐ, ์์ฒญ ๋ด์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ ์ด ๋์ผํ ํธ๋์ญ์ ๋ด์์ ์ํ๋๋๋ก ๋ณด์ฅํฉ๋๋ค.
const { AsyncLocalStorage } = require('async_hooks');
const express = require('express');
const { Sequelize } = require('sequelize');
const asyncLocalStorage = new AsyncLocalStorage();
const app = express();
// Configure Sequelize
const sequelize = new Sequelize('database', 'user', 'password', {
dialect: 'sqlite',
storage: ':memory:', // Use in-memory database for example
logging: false,
});
// Define a model
const User = sequelize.define('User', {
username: Sequelize.STRING,
});
// Middleware to manage transactions
const transactionMiddleware = async (req, res, next) => {
const transaction = await sequelize.transaction();
asyncLocalStorage.run(new Map(), async () => {
asyncLocalStorage.getStore().set('transaction', transaction);
try {
await next();
await transaction.commit();
} catch (error) {
await transaction.rollback();
console.error('Transaction rolled back:', error);
res.status(500).send('Transaction failed');
}
});
};
app.use(transactionMiddleware);
app.post('/users', async (req, res) => {
const transaction = asyncLocalStorage.getStore().get('transaction');
try {
// Example: Create a user
const user = await User.create({
username: 'testuser',
}, { transaction });
res.status(201).send(`User created with ID: ${user.id}`);
} catch (error) {
console.error('Error creating user:', error);
throw error; // Propagate the error to trigger rollback
}
});
// Sync the database and start the server
sequelize.sync().then(() => {
app.listen(3000, () => {
console.log('Server listening on port 3000');
});
});
์ด ์์ ์์๋:
transactionMiddleware๋ Sequelize ํธ๋์ญ์ ์ ์์ฑํ๊ณ ์ด๋ฅผ ALS์ ์ ์ฅํฉ๋๋ค.- ์์ฒญ ํธ๋ค๋ฌ ๋ด์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ ์ ALS์์ ํธ๋์ญ์ ์ ๊ฒ์ํ์ฌ ์ฌ์ฉํฉ๋๋ค.
- ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด ํธ๋์ญ์ ์ด ๋กค๋ฐฑ๋์ด ๋ฐ์ดํฐ ์ผ๊ด์ฑ์ ๋ณด์ฅํฉ๋๋ค.
๊ณ ๊ธ ์ฌ์ฉ๋ฒ ๋ฐ ๊ณ ๋ ค ์ฌํญ
๊ธฐ๋ณธ ์์ ๋ฅผ ๋์ด์, ALS๋ฅผ ์ฌ์ฉํ ๋ ๋ค์์ ๊ณ ๊ธ ์ฌ์ฉ ํจํด๊ณผ ์ค์ํ ๊ณ ๋ ค ์ฌํญ์ ๊ณ ๋ คํ์ญ์์ค:
- ALS ์ธ์คํด์ค ์ค์ฒฉ: ALS ์ธ์คํด์ค๋ฅผ ์ค์ฒฉํ์ฌ ๊ณ์ธต์ ์ปจํ ์คํธ๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ ์ฌ์ ์ธ ๋ณต์ก์ฑ์ ์ ์ํ๊ณ ์ปจํ ์คํธ ๊ฒฝ๊ณ๊ฐ ๋ช ํํ๊ฒ ์ ์๋๋๋ก ํด์ผ ํฉ๋๋ค. ์ค์ฒฉ๋ ALS ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํ ๋๋ ์ ์ ํ ํ ์คํธ๊ฐ ํ์์ ์ ๋๋ค.
- ์ฑ๋ฅ ์ํฅ: ALS๋ ์๋นํ ์ด์ ์ ์ ๊ณตํ์ง๋ง ์ ์ฌ์ ์ธ ์ฑ๋ฅ ์ค๋ฒํค๋๋ฅผ ์ธ์งํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ์ ์ฅ ๊ณต๊ฐ์ ์์ฑํ๊ณ ์ ๊ทผํ๋ ๊ฒ์ ์ฑ๋ฅ์ ์ฝ๊ฐ์ ์ํฅ์ ๋ฏธ์น ์ ์์ต๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ ํ๋กํ์ผ๋งํ์ฌ ALS๊ฐ ๋ณ๋ชฉ ํ์์ ์ผ์ผํค์ง ์๋์ง ํ์ธํ์ญ์์ค.
- ์ปจํ
์คํธ ์ ์ถ: ์ปจํ
์คํธ๋ฅผ ์๋ชป ๊ด๋ฆฌํ๋ฉด ํ ์์ฒญ์ ๋ฐ์ดํฐ๊ฐ ๋ค๋ฅธ ์์ฒญ์ ์๋์น ์๊ฒ ๋
ธ์ถ๋๋ ์ปจํ
์คํธ ์ ์ถ๋ก ์ด์ด์ง ์ ์์ต๋๋ค. ์ด๋ ํนํ
enterWith๋ฐexit๋ฅผ ์ฌ์ฉํ ๋ ๊ด๋ จ์ด ์์ต๋๋ค. ์ ์คํ ์ฝ๋ฉ ๊ดํ๊ณผ ์ฒ ์ ํ ํ ์คํธ๋ ์ปจํ ์คํธ ์ ์ถ์ ๋ฐฉ์งํ๋ ๋ฐ ๋งค์ฐ ์ค์ํฉ๋๋ค. ์ ์ฌ์ ์ธ ๋ฌธ์ ๋ฅผ ๊ฐ์งํ๊ธฐ ์ํด ๋ฆฐํ ๊ท์น์ด๋ ์ ์ ๋ถ์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๊ณ ๋ คํ์ญ์์ค. - ๋ก๊น ๋ฐ ๋ชจ๋ํฐ๋ง๊ณผ์ ํตํฉ: ALS๋ ๋ก๊น ๋ฐ ๋ชจ๋ํฐ๋ง ์์คํ ๊ณผ ์ํํ๊ฒ ํตํฉ๋์ด ์ ํ๋ฆฌ์ผ์ด์ ์ ๋์์ ๋ํ ๊ท์คํ ํต์ฐฐ๋ ฅ์ ์ ๊ณตํ ์ ์์ต๋๋ค. ๋ก๊ทธ ๋ฉ์์ง์ ์์ฒญ ID ๋๋ ๊ธฐํ ๊ด๋ จ ์ปจํ ์คํธ ์ ๋ณด๋ฅผ ํฌํจํ์ฌ ๋๋ฒ๊น ๋ฐ ๋ฌธ์ ํด๊ฒฐ์ ์ฉ์ดํ๊ฒ ํ์ญ์์ค. OpenTelemetry์ ๊ฐ์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ์๋น์ค ๊ฐ์ ์ปจํ ์คํธ๋ฅผ ์๋์ผ๋ก ์ ํํ๋ ๊ฒ์ ๊ณ ๋ คํ์ญ์์ค.
- ALS์ ๋์: ALS๋ ๊ฐ๋ ฅํ ๋๊ตฌ์ด์ง๋ง ๋ชจ๋ ์๋๋ฆฌ์ค์ ํญ์ ์ต์์ ์๋ฃจ์ ์ ์๋๋๋ค. ์ปจํ ์คํธ ๊ฐ์ฒด๋ฅผ ๋ช ์์ ์ผ๋ก ์ ๋ฌํ๊ฑฐ๋ ์์กด์ฑ ์ฃผ์ ์ ์ฌ์ฉํ๋ ๊ฒ๊ณผ ๊ฐ์ ๋์์ ์ธ ์ ๊ทผ ๋ฐฉ์์ด ์ ํ๋ฆฌ์ผ์ด์ ์ ์๊ตฌ์ ๋ ์ ํฉํ๋ค๋ฉด ๊ณ ๋ คํ์ญ์์ค. ์ปจํ ์คํธ ๊ด๋ฆฌ ์ ๋ต์ ์ ํํ ๋ ๋ณต์ก์ฑ, ์ฑ๋ฅ ๋ฐ ์ ์ง๋ณด์์ฑ ๊ฐ์ ์ ์ถฉ์ ์ ํ๊ฐํ์ญ์์ค.
๊ธ๋ก๋ฒ ๊ด์ ๋ฐ ๊ตญ์ ์ ๊ณ ๋ ค ์ฌํญ
๊ธ๋ก๋ฒ ๊ณ ๊ฐ์ ์ํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐํ ๋ ALS๋ฅผ ์ฌ์ฉํ๋ฉด์ ๋ค์์ ๊ตญ์ ์ ์ธก๋ฉด์ ๊ณ ๋ คํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค:
- ์๊ฐ๋: ๋ค๋ฅธ ์๊ฐ๋์ ์ฌ์ฉ์์๊ฒ ๋ ์ง์ ์๊ฐ์ด ์ฌ๋ฐ๋ฅด๊ฒ ํ์๋๋๋ก ALS์ ์๊ฐ๋ ์ ๋ณด๋ฅผ ์ ์ฅํ์ญ์์ค. Moment.js๋ Luxon๊ณผ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ์๊ฐ๋ ๋ณํ์ ์ฒ๋ฆฌํ์ญ์์ค. ์๋ฅผ ๋ค์ด, ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธํ ํ ์ ํธํ๋ ์๊ฐ๋๋ฅผ ALS์ ์ ์ฅํ ์ ์์ต๋๋ค.
- ํ์งํ: ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ฌ๋ฐ๋ฅธ ์ธ์ด๋ก ํ์๋๋๋ก ์ฌ์ฉ์์ ์ ํธ ์ธ์ด ๋ฐ ๋ก์บ์ ALS์ ์ ์ฅํ์ญ์์ค. i18next์ ๊ฐ์ ํ์งํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฒ์ญ์ ๊ด๋ฆฌํ์ญ์์ค. ์ฌ์ฉ์์ ๋ก์บ์ ๊ทธ๋ค์ ๋ฌธํ์ ์ ํธ๋์ ๋ฐ๋ผ ์ซ์, ๋ ์ง, ํตํ๋ฅผ ํ์ํํ๋ ๋ฐ ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
- ํตํ: ๊ฐ๊ฒฉ์ด ์ฌ๋ฐ๋ฅด๊ฒ ํ์๋๋๋ก ์ฌ์ฉ์์ ์ ํธ ํตํ๋ฅผ ALS์ ์ ์ฅํ์ญ์์ค. ํตํ ๋ณํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ํตํ ๋ณํ์ ์ฒ๋ฆฌํ์ญ์์ค. ์ฌ์ฉ์์ ํ์ง ํตํ๋ก ๊ฐ๊ฒฉ์ ํ์ํ๋ฉด ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์ ํ๊ณ ์ ํ์จ์ ๋์ผ ์ ์์ต๋๋ค.
- ๋ฐ์ดํฐ ํ๋ผ์ด๋ฒ์ ๊ท์ : ALS์ ์ฌ์ฉ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ๋ GDPR๊ณผ ๊ฐ์ ๋ฐ์ดํฐ ํ๋ผ์ด๋ฒ์ ๊ท์ ์ ์ ์ํ์ญ์์ค. ์ ํ๋ฆฌ์ผ์ด์ ์ด์์ ํ์ํ ๋ฐ์ดํฐ๋ง ์ ์ฅํ๊ณ ๋ฐ์ดํฐ๋ฅผ ์์ ํ๊ฒ ์ฒ๋ฆฌํ๊ณ ์๋์ง ํ์ธํ์ญ์์ค. ๋ฌด๋จ ์ ๊ทผ์ผ๋ก๋ถํฐ ์ฌ์ฉ์ ๋ฐ์ดํฐ๋ฅผ ๋ณดํธํ๊ธฐ ์ํด ์ ์ ํ ๋ณด์ ์กฐ์น๋ฅผ ๊ตฌํํ์ญ์์ค.
๊ฒฐ๋ก
JavaScript Async Local Storage๋ ๋น๋๊ธฐ JavaScript ์ ํ๋ฆฌ์ผ์ด์ ์์ ์์ฒญ ์ปจํ ์คํธ๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํ ๊ฒฌ๊ณ ํ๊ณ ์ฐ์ํ ์๋ฃจ์ ์ ์ ๊ณตํฉ๋๋ค. ALS ๋ด์ ์ปจํ ์คํธ๋ณ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํจ์ผ๋ก์จ ์ฝ๋๋ฅผ ๋จ์ํํ๊ณ , ์ ์ง๋ณด์์ฑ์ ํฅ์์ํค๋ฉฐ, ๋๋ฒ๊น ๋ฅ๋ ฅ์ ๊ฐํํ ์ ์์ต๋๋ค. ์ด ๊ฐ์ด๋์์ ์ค๋ช ํ ํต์ฌ ๊ฐ๋ ๊ณผ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ดํดํ๋ฉด, ํ๋ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ๋ณต์ก์ฑ์ ์ฒ๋ฆฌํ ์ ์๋ ํ์ฅ ๊ฐ๋ฅํ๊ณ ์ ๋ขฐํ ์ ์๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๊ธฐ ์ํด ALS๋ฅผ ํจ๊ณผ์ ์ผ๋ก ํ์ฉํ ์ ์๊ฒ ๋ ๊ฒ์ ๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ ์ต์ ์ฑ๋ฅ๊ณผ ๋ณด์์ ๋ณด์ฅํ๊ธฐ ์ํด ํญ์ ์ฑ๋ฅ ์ํฅ๊ณผ ์ ์ฌ์ ์ธ ์ปจํ ์คํธ ์ ์ถ ๋ฌธ์ ๋ฅผ ๊ณ ๋ คํ๋ ๊ฒ์ ์์ง ๋ง์ญ์์ค. ALS๋ฅผ ์ฑํํ๋ฉด ๋น๋๊ธฐ ์ํฌํ๋ก์ฐ๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐ ์์ด ์๋ก์ด ์์ค์ ๋ช ํ์ฑ๊ณผ ์ ์ด๋ ฅ์ ํ๋ณดํ๊ฒ ๋๋ฉฐ, ๊ถ๊ทน์ ์ผ๋ก ๋ ํจ์จ์ ์ด๊ณ ์ ์ง๋ณด์ํ๊ธฐ ์ฌ์ด ์ฝ๋๋ก ์ด์ด์ง๋๋ค.